package org.wx.herostory.services.rank;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.wx.herostory.services.processor.async.AsyncOperationProcessor;
import org.wx.herostory.services.processor.async.IAsyncOperation;
import org.wx.herostory.services.util.RedisUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * @description: 排行榜服务
 * @author: wangxun
 * @createDate: 2021/3/8
 * @version: 1.0
 */
@Slf4j
public class RankService {
    static private RankService _instance = new RankService();

    private RankService(){}

    static public RankService getInstance(){
        return _instance;
    }

    /**
     * 获取排行榜
     * @param callback 回调函数
     */
    public void getRank(Function<List<RankItem>,Void> callback){
        if(null == callback){
            return;
        }
        AsyncOperationProcessor.getInstance().process(new AsyncGetRank(){
            @Override
            public void doFinish() {
                callback.apply(this.getRankItemList());
            }
        });
    }


    static private class AsyncGetRank implements IAsyncOperation{
        /**
         * 排名条目列表
         */
        private List<RankItem> _rankItemList;

        public List<RankItem> getRankItemList() {
            return _rankItemList;
        }

        @Override
        public void doAsync() {
            try(Jedis jedis = RedisUtil.getJedis()) {
                final Set<Tuple> rank = jedis.zrevrangeWithScores("Rank", 0, 9);
                List<RankItem> rankItemList = new ArrayList<>();
                int i =0;
                for (Tuple tuple : rank) {
                    if(null == tuple){
                        continue;
                    }
                    // 用户ID
                    final int userId = Integer.parseInt(tuple.getElement());
                    // 用户信息
                    final String jsonStr = jedis.hget("User_" + userId, "BasicInfo");
                    if(null == jsonStr){
                        continue;
                    }
                    final RankItem rankItem = new RankItem();
                    // 排名
                    rankItem.setRankId(++i);
                    // userId
                    rankItem.setUserId(userId);
                    // 赢得次数
                    rankItem.setWin((int)tuple.getScore());

                    final JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                    rankItem.setUserName(jsonObject.getString("userName"));
                    rankItem.setHeroAvatar(jsonObject.getString("heroAvatar"));

                    rankItemList.add(rankItem);
                }
                // 赋值用于回调
                _rankItemList = rankItemList;
            }
        }


        @Override
        public int getBindId() {
            return 0;
        }
    }

    /**
     * 为排行榜进程做入库redis
     * @param winnerId
     * @param loserId
     */
    public void refreshRank(int winnerId , int loserId){
        if(winnerId<=0 || loserId<=0){
            return;
        }
        try(Jedis jedis = RedisUtil.getJedis()) {
            // 为用户的win值加1
            jedis.hincrBy("User_" + winnerId, "Win", 1);
            jedis.hincrBy("User_" + loserId, "Lose", 1);

            final String win = jedis.hget("User_" + winnerId, "Win");

            jedis.zadd("Rank", Integer.parseInt(win), String.valueOf(winnerId));

        }catch (Exception e){
            log.info(e.getMessage(),e);
        }
    }
}
